package main

import (
	"embed"
	"errors"
	"log"
	"net/http"
	"os"

	"apiote.xyz/p/asgard/eostre"
	"apiote.xyz/p/asgard/gersemi"
	"apiote.xyz/p/asgard/hermodr"
	"apiote.xyz/p/asgard/himinbjorg"
	"apiote.xyz/p/asgard/jotunheim"
	"apiote.xyz/p/asgard/mimir"
	"apiote.xyz/p/asgard/tyr"

	"git.sr.ht/~sircmpwn/getopt"
)

//go:embed templates
var templatesFS embed.FS

func main() {
	var (
		configPath string
		dbPath     string
	)
	getopt.StringVar(&configPath, "c", "", "path to config file")
	getopt.StringVar(&dbPath, "b", "", "path to database file")
	getopt.Parse()

	config, err := jotunheim.Read(configPath)
	if err != nil {
		log.Fatalln(err)
	}

	db, err := himinbjorg.Migrate(dbPath)
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()
	log.Println("Migrated")

	args := getopt.Args()
	switch args[0] {
	case "hermodr":
		fallthrough
	case "hermóðr":
		hermodr.Hermodr(config)

	case "tyr":
		fallthrough
	case "týr":
		if len(args) == 1 {
			tyr.Tyr(db, config)
		} else {
			switch args[1] {
			case "list":
				tyr.ListLocks(db)
			case "offend":
				if len(args) == 2 {
					log.Fatalln("missing token")
				}
				tyr.Release(db, config, args[2], "*", config.Tyr.ImapFolderJunk)
			case "release":
				if len(args) == 2 {
					log.Fatalln("missing token (and recipient)")
				}
				addressTo := ""
				if len(args) != 3 {
					addressTo = args[3]
				}
				tyr.Release(db, config, args[2], addressTo, config.Tyr.ImapFolderInbox)
			}
		}

	case "mimir":
		fallthrough
	case "mímir":
		mimir.Mimir(db, config)

	case "ēostre":
		fallthrough
	case "eostre":
		n, err := eostre.Eostre(config)
		if err != nil {
			log.Println(err)
			return
		}
		_, err = os.Stat("diary.epub")
		if err != nil && errors.Is(err, os.ErrNotExist) {
			if n == 0 {
				return
			}
			err = eostre.DownloadDiary(config)
			if err != nil {
				log.Println(err)
				return
			}
		}
		if n > 0 {
			err = eostre.UpdateDiary(config)
			if err != nil {
				log.Println(err)
				return
			}
		}
		err = eostre.SendDiary(config)
		if err != nil {
			log.Println(err)
			return
		}

	case "gersemi":
		log.Println(gersemi.Gersemi(config))

	case "serve":
		http.HandleFunc("/tyr", tyr.Serve(db, config, templatesFS))
		http.HandleFunc("/mimir", mimir.Serve(db, templatesFS))
		http.HandleFunc("/mimir/", mimir.Serve(db, templatesFS))
		e := http.ListenAndServe(":8081", nil)
		if e != nil {
			log.Println(e)
		}
	}

}
